package org.tloss.web.editor.sql.editors;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;
import org.tloss.web.editor.Utils;
import org.tloss.web.editor.database.editors.jdbc.Column;
import org.tloss.web.editor.database.editors.jdbc.Table;
import org.tloss.web.editor.model.Database;
import org.tloss.web.editor.model.Param;
import org.tloss.web.editor.model.Sql;
import org.tloss.web.editor.model.oper.logical.CompareLogical;
import org.tloss.web.editor.model.oper.logical.CompareOperator;
import org.tloss.web.editor.model.oper.math.ColumnOperand;
import org.tloss.web.editor.model.oper.math.MathOperand;
import org.tloss.web.editor.model.oper.math.ParamOparand;
import org.tloss.web.editor.utils.LogicalBuilder;

public class SqlBuilderEditor extends EditorPart {

	IResourceChangeListener dirtyListener;

	public void setDirtyListener(IResourceChangeListener dirtyListener) {
		this.dirtyListener = dirtyListener;
		builder.setDirtyListener(dirtyListener);
	}

	Sql sql = null;

	public void setSql(Sql sql) {
		this.sql = sql;
		builder.setLogicalProvider(sql);
	}

	public void doSave(IProgressMonitor monitor) {

	}

	public void doSaveAs() {

	}

	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		if (!(input instanceof IFileEditorInput)) {
			PartInitException exception =  new PartInitException("Input must be a file");
			Utils.logError("Input must be a file", exception);
			throw  exception;
		}
		setSite(site);
		setInput(input);
	}

	public boolean isDirty() {
		return false;
	}

	public boolean isSaveAsAllowed() {

		return false;
	}

	LogicalBuilder builder = new LogicalBuilder() {

		public List<Object> getOperandList() {
			List<Object> operands = new ArrayList<Object>();
			operands.add(null);
			Database database = sql.getDatabase();
			List<Table> tables = sql.getTables();
			if (database != null && tables != null && tables.size() > 0) {
				List<Table> tables2 = database.getTables();
				if (tables2 != null && tables2.size() > 0) {
					int index = -1;
					List<Column> columns;
					Table table;
					ColumnOperand columnOperand;
					for (int i = 0; i < tables.size(); i++) {
						index = tables2.indexOf(tables.get(i));
						if (index != -1) {
							table = tables2.get(index);
							columns = table.getColumns();
							if (columns != null) {
								for (int j = 0; j < columns.size(); j++) {
									columnOperand = new ColumnOperand();
									columnOperand.setTable(tables.get(i));
									columnOperand.setColumn(columns.get(j));
									operands.add(columnOperand);
								}
							}
						}
					}
				}
			}
			List<Param> params = sql.getParams();
			if (params != null) {
				ParamOparand oparand;
				for (int i = 0; i < params.size(); i++) {
					oparand = new ParamOparand();
					oparand.setParam(params.get(i));
					operands.add(oparand);
				}
			}
			return operands;
		}

		@Override
		public EditingSupport getOperand1EditingSupport(
				final TreeViewer treeViewer) {
			EditingSupport editingSupport1 = new EditingSupport(treeViewer) {
				protected void setValue(Object arg0, Object arg1) {
					if (arg0 != null && arg0 instanceof CompareLogical) {
						((CompareLogical) arg0)
								.setOperand1((MathOperand) operands
										.get((Integer) arg1));
						treeViewer.refresh();
						if (dirtyListener != null) {
							dirtyListener.resourceChanged(null);
						}
					}

				}

				protected Object getValue(Object arg0) {
					if (arg0 != null && arg0 instanceof CompareLogical) {
						MathOperand mathOperand = ((CompareLogical) arg0)
								.getOperand1();
						if (mathOperand != null && operands != null) {
							return operands.indexOf(mathOperand);
						}
					}
					return 0;
				}

				ComboBoxCellEditor libEditor = null;
				List<Object> operands = null;

				protected CellEditor getCellEditor(Object arg0) {
					if (libEditor == null) {
						operands = getOperandList();
						libEditor = new ComboBoxCellEditor(
								(Composite) treeViewer.getControl(),
								getOperandListSupport(operands));
					}

					return libEditor;
				}

				protected boolean canEdit(Object arg0) {
					if (arg0 instanceof CompareLogical)
						return true;
					return false;
				}
			};

			return editingSupport1;
		}

		@Override
		public EditingSupport getOperand2EditingSupport(
				final TreeViewer treeViewer) {
			EditingSupport editingSupport2 = new EditingSupport(treeViewer) {
				protected void setValue(Object arg0, Object arg1) {
					if (arg0 != null && arg0 instanceof CompareLogical) {
						((CompareLogical) arg0)
								.setOperand2((MathOperand) operands
										.get((Integer) arg1));
						treeViewer.refresh();
						if (dirtyListener != null) {
							dirtyListener.resourceChanged(null);
						}
					}

				}

				protected Object getValue(Object arg0) {
					if (arg0 != null && arg0 instanceof CompareLogical) {
						MathOperand mathOperand = ((CompareLogical) arg0)
								.getOperand2();
						if (mathOperand != null && operands != null) {
							return operands.indexOf(mathOperand);
						}
					}
					return 0;
				}

				ComboBoxCellEditor libEditor = null;
				List<Object> operands = null;

				protected CellEditor getCellEditor(Object arg0) {
					if (libEditor == null) {
						operands = getOperandList();
						libEditor = new ComboBoxCellEditor(
								(Composite) treeViewer.getControl(),
								getOperandListSupport(operands));
					}

					return libEditor;
				}

				protected boolean canEdit(Object arg0) {
					if (arg0 != null && arg0 instanceof CompareLogical) {
						CompareOperator operator = ((CompareLogical) arg0)
								.getOperator();
						if (operator != null && !operator.supportTwoOperand()) {
							return false;
						}
						return true;
					}
					return false;
				}
			};

			return editingSupport2;
		}

	};

	public void createPartControl(Composite parent) {
		builder.createPartControl(parent);
	}

	public void setFocus() {

	}

}
